package cn.mdmm.user.service.impl.user;

import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;

import org.apache.commons.beanutils.PropertyUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.dubbo.config.annotation.Service;

import cn.mdmm.user.common.MessageConstant;
import cn.mdmm.user.entity.response.ResponseBodyToOne;
import cn.mdmm.user.entity.system.SysRole;
import cn.mdmm.user.entity.system.SysRoleUser;
import cn.mdmm.user.entity.system.SysUser;
import cn.mdmm.user.entity.user.request.UserRequest;
import cn.mdmm.user.entity.user.request.UserUpdatePwdRequest;
import cn.mdmm.user.mapper.system.SysRoleUserMapper;
import cn.mdmm.user.mapper.user.UserMapper;
import cn.mdmm.user.service.system.SysRoleService;
import cn.mdmm.user.service.user.UserCodeInfoService;
import cn.mdmm.user.service.user.UserService;
import cn.modoumama.common.exception.RequiredException;
import cn.modoumama.common.exception.ServiceException;
import cn.modoumama.common.response.Response;
import cn.modoumama.common.utils.PasswordUtils;
import cn.modoumama.common.utils.StringUtils;
import cn.modoumama.redis.service.RedisService;
import cn.modoumama.service.base.impl.BaseServiceImpl;

@Service(version = "1.0", validation="true")
public class UserServiceImpl extends BaseServiceImpl<SysUser, Long> implements UserService {
	Logger logger = LoggerFactory.getLogger(getClass());
	@Autowired
	private SysRoleUserMapper roleUsermapper;
	@Autowired
	private UserCodeInfoService userCodeInfoService;
	@Autowired
	private SysRoleUserMapper sRoleUserMapper;
	@Autowired
	SysRoleService sysRoleService;
	@Autowired
	private RedisService redisService;
	@Autowired
	public void setMapper(UserMapper mapper) {
		setGenericMapper(mapper);
	}

	/**
	 * 用户登陆的token,保存用户的信息
	 */
	public static final String token_key = "token_key_";
	/**
	 * 保存的用户登陆的token信息，后面接userId
	 */
	public static final String user_token = "user_token_";

	@Override
	public Integer insert(SysUser record) {
		int count = 0;

		record.setUserStatus(1);
		record.setCreateTime(new Date());
		record.setUpdateTime(new Date());
		record.setUserPwd(PasswordUtils.getPassword(record.getUserName(), record.getUserPwd()));
		count = super.insert(record);
		return count;
	}

	@Override
	public List<SysRoleUser> getRoleIds(Long userId) {
		SysRoleUser roleUser = new SysRoleUser();
		roleUser.setUserId(userId);
		List<SysRoleUser> roleUsers = roleUsermapper.getListByModel(roleUser);
		return roleUsers;
	}

	@Override
	public Integer updateById(SysUser record) {
		record.setUpdateTime(new Date());
		int flag = super.updateById(record);
		return flag;
	}

	@Override
	public void updateUserPwd(Long id, String userPwd, String newPwd, String confirmPwd) {
		SysUser user = new SysUser();
		user.setId(id);
		SysUser record = findObjectByModel(user);
		if (StringUtils.isNotBlank(userPwd)) {
			userPwd = PasswordUtils.getPassword(record.getUserName(), userPwd);
			if (!userPwd.equals(record.getUserPwd())) {
				throw new ServiceException(MessageConstant.PASSWORD_ERROR);
			}
		}

		if (newPwd.equals(confirmPwd)) {
			newPwd = PasswordUtils.getPassword(record.getUserName(), newPwd);
			record.setUserPwd(newPwd);
			record.setUpdateTime(new Date());
			super.updateById(record);

		} else {
			throw new ServiceException(MessageConstant.NEW_PASSWORD_DIVERSE);
		}
	}

	@Override
	public Integer removeByIds(Long[] userIds) {
		int count = 0;
		for (Long userId : userIds) {
			// 删除用户
			removeById(userId);
			// 删除用户和角色的绑定关系
			Map<String, Object> condition = new HashMap<String, Object>();
			condition.put("userId", userId);
			count = roleUsermapper.deleteByCondition(condition);
		}
		return count;
	}

	@Override
	public Response checkUser(UserRequest request) {
		Response response = new Response();
		SysUser sysUser = copyValue(request);
		sysUser = findObjectByModel(sysUser);
		if (sysUser != null) {
			throw new ServiceException(MessageConstant.USER_DOES_IS_EXIST);
		}
		return response;
	}

	@Override
	public ResponseBodyToOne register(UserRequest request) {
		ResponseBodyToOne responseBodyToOne = new ResponseBodyToOne();
		String code = request.getCode();
		String phone = request.getPhone();
		userCodeInfoService.verificationCode(phone, code);

		SysUser sysUser = new SysUser();
		if (StringUtils.isNotBlank(request.getUserName())) {
			sysUser.setUserName(request.getUserName());
			sysUser = findObjectByModel(sysUser);
			if (sysUser != null) {
				throw new ServiceException(MessageConstant.LOGIN_NAME_DOES_IS_EXIST);
			}
		}
		if (StringUtils.isNotBlank(request.getEmail())) {
			sysUser.setEmail(request.getEmail());
			sysUser = findObjectByModel(sysUser);
			if (sysUser != null) {
				throw new ServiceException(MessageConstant.EMAIL_DOES_IS_EXIST);
			}
		}

		// 设置默认登陆名为手机号
		if (StringUtils.isBlank(request.getUserName())) {
			request.setUserName(phone);
		}

		sysUser = copyValue(request);
		sysUser.setUserType(3);
		// 设置默认密码为手机号
		if (StringUtils.isBlank(sysUser.getUserPwd())) {
			sysUser.setUserPwd(phone);
		}
		insert(sysUser);
		responseBodyToOne.setData(getUser(sysUser));
		return responseBodyToOne;
	}

	@Override
	public ResponseBodyToOne login(UserRequest request) {
		ResponseBodyToOne responseBodyToOne = new ResponseBodyToOne();
		SysUser user = null;
		if (StringUtils.isNotBlank(request.getPhone())) {
			if (StringUtils.isNotBlank(request.getCode())) {
				userCodeInfoService.verificationCode(request.getPhone(), request.getCode());
				user = new SysUser();
				user.setPhone(request.getPhone());
				user = findObjectByModel(user);
			} else if (StringUtils.isNotBlank(request.getUserPwd())) {
				user = getUser(request.getPhone(), null, request.getUserPwd());
			} else {
				throw new RequiredException("code");
			}
		} else if (StringUtils.isBlank(request.getUserName())) {
			throw new RequiredException("phone");
		} else if (StringUtils.isBlank(request.getUserPwd())) {
			throw new RequiredException("userPwd");
		} else {
			user = getUser(request.getPhone(), request.getUserName(), request.getUserPwd());
		}

		if (user == null) {
			throw new ServiceException(MessageConstant.USER_DOES_NOT_EXIST);
		} else {
			// 当前token
			String token = StringUtils.getToken();
			// 保存用户的唯一token
			saveToken(user, token);
			user.setToken(token);
			responseBodyToOne.setData(getUser(user));
		}

		return responseBodyToOne;
	}

	private SysUser getUser(String phone, String userName, String userPwd) {
		SysUser user = new SysUser();
		if (StringUtils.isNotBlank(phone)) {
			user.setPhone(phone);
		} else if (StringUtils.isNotBlank(userName)) {
			user.setUserName(userName);
		}
		user = findObjectByModel(user);
		if (user == null) {
			throw new ServiceException(MessageConstant.USER_DOES_NOT_EXIST);
		}
		if (!user.getUserPwd().equals(PasswordUtils.getPassword(user.getUserName(), userPwd))) {
			throw new ServiceException(MessageConstant.PASSWORD_ERROR);
		}

		return user;
	}

	private SysUser copyValue(UserRequest request) {
		SysUser user = new SysUser();
		try {
			PropertyUtils.copyProperties(user, request);
		} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
			logger.info("");
		}

		return user;
	}

	@Override
	public Response updatePwd(UserUpdatePwdRequest request) {
		Response response = new Response();
		if (StringUtils.isBlank(request.getNewPwd())) {
			throw new RequiredException("newPwd");
		}
		if (StringUtils.isBlank(request.getConfirmPwd())) {
			throw new RequiredException("confirmPwd");
		}
		updateUserPwd(request.getUserId(), request.getUserPwd(), request.getNewPwd(), request.getConfirmPwd());
		return response;
	}

	@Override
	public Response resetPwd(UserUpdatePwdRequest request) {
		Response response = new Response();
		if (StringUtils.isBlank(request.getPhone())) {
			throw new RequiredException("phone");
		}

		if (StringUtils.isBlank(request.getCode())) {
			throw new RequiredException("code");
		}

		if (StringUtils.isBlank(request.getNewPwd())) {
			throw new RequiredException("newPwd");
		}
		if (StringUtils.isBlank(request.getConfirmPwd())) {
			throw new RequiredException("confirmPwd");
		}

		SysUser sysUser = new SysUser();
		sysUser.setPhone(request.getPhone());
		sysUser = findObjectByModel(sysUser);
		if (sysUser == null) {
			throw new ServiceException(MessageConstant.USER_DOES_NOT_EXIST);
		}
		updateUserPwd(sysUser.getId(), null, request.getNewPwd(), request.getConfirmPwd());

		// 验证验证码
		userCodeInfoService.verificationCode(request.getPhone(), request.getCode());
		return response;
	}

	@Override
	public ResponseBodyToOne updateUser(UserRequest request) {
		ResponseBodyToOne responseBodyToOne = new ResponseBodyToOne();
		SysUser user = new SysUser();
		user.setId(request.getUserId());
		user = findObjectByModel(user);
		user.setRealName(request.getRealName());
		user.setSex(request.getSex());
		user.setHeadImgUrl(request.getHeadImgUrl());
		updateById(user);
		responseBodyToOne.setData(getUser(user));
		return responseBodyToOne;
	}

	@Override
	public SysUser bindRoleUser(Integer roleType, Long userId, Long[] roleIds) {
		SysUser user = null;
		if (userId != null && roleIds != null) {
			user = findById(userId);
			if (user != null) {
				Map<String, Object> condition = new HashMap<String, Object>();
				condition.put("userId", userId);
				sRoleUserMapper.deleteByCondition(condition);
				for (int i = 0; i < roleIds.length; i++) {
					SysRole role = sysRoleService.getRole(roleIds[i]);
					if (role == null || role.getRoleType() < roleType) {
						continue;
					}
					if (roleIds[i] != 1 && roleIds[i] != 2) {
						SysRoleUser record = new SysRoleUser();
						record.setRoleId(roleIds[i]);
						record.setUserId(userId);
						sRoleUserMapper.insertModel(record);
					}
				}
			}
		}
		return user;
	}

	@Override
	public List<SysRole> getAllRole(Long userId) {
		SysUser sysUser = findById(userId);
		Map<String, Object> condition = new HashMap<String, Object>();
		condition.put("roleType", sysUser.getUserType());
		List<SysRole> roles = sysRoleService.findModelsByCondition(condition);

		List<SysRoleUser> roleUsers = getRoleIds(userId);
		// 获取SysRole的id集合
		Set<Long> roleIds = new HashSet<>();
		for (SysRoleUser roleUser1 : roleUsers) {
			roleIds.add(roleUser1.getRoleId());
		}
		// 设置用户是否正在使用
		for (Iterator<SysRole> iterator = roles.iterator(); iterator.hasNext();) {
			SysRole role = iterator.next();
			if (roleIds.contains(role.getRoleId())) {
				role.setIsUse(true);
			} else {
				role.setIsUse(false);
			}
		}
		return roles;
	}

	/** 接口返回数据前，去掉密码和创建时间 */
	private SysUser getUser(SysUser user) {
		user.setUserPwd(null);
		user.setCreateTime(null);
		user.setUpdateTime(null);
		return user;
	}

	/**
	 * <p>
	 * 保存用户的唯一token
	 * </p>
	 *
	 * @param user
	 * @param token
	 * @return 创建人：邓强 <br>
	 *         创建时间：2017年7月18日 下午4:28:11 <br>
	 * @throws ExecutionException
	 * @throws InterruptedException
	 */
	private void saveToken(SysUser user, String token) {
		// 删除之前的登陆信息
		String oldToken = (String) redisService.getStr(user_token + user.getId());
		redisService.delete(token_key + oldToken);
		// 保存用户的token
		redisService.set(token_key + token, user);
		redisService.set(user_token + user.getId(), token);
	}

	@Override
	public Long getUserByToken(String sessionKey) {
		return (Long) redisService.get(token_key+sessionKey);
	}
}
